package com.forezp.rule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;

/**
 * @author jiangzh-a
 * @version 1.0
 * @date 2020/12/15 21:37
 */
public class WeightedRule extends AbstractLoadBalancerRule {

    private int total = 0;        //总共被调用的次数，目前要求每台被调用5次
    private int currentIndex = 0; //当前提供服务的机器号

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
        //读取配置文件并且初始化,ribbon内部的 几乎用不上
    }

    @Override
    public Server choose(Object key) {
        try {
            System.out.println("key:" + key);
            BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) this.getLoadBalancer();

            System.out.println("baseLoadBalancer‐‐‐>:" + baseLoadBalancer);
            //获取微服务的名称
            String serviceName = baseLoadBalancer.getName();
            Server server = null;

            while (server == null) {
                if (Thread.interrupted()) {
                    return null;
                }
                List<Server> upList = baseLoadBalancer.getReachableServers();
                List<Server> allList = baseLoadBalancer.getAllServers();

                int serverCount = allList.size();
                if (serverCount == 0) {
                    return null;
                }

                if (total < 5) {
                    server = upList.get(currentIndex);
                    total++;
                } else {
                    total = 0;
                    currentIndex++;
                    if (currentIndex >= upList.size()) {
                        currentIndex = 0;
                    }
                }

                if (server == null) {
                    /*
                     * The only time this should happen is if the server list were
                     * somehow trimmed. This is a transient condition. Retry after
                     * yielding.
                     */
                    Thread.yield();
                    continue;
                }

                if (server.isAlive()) {
                    return (server);
                }

                // Shouldn't actually happen.. but must be transient or a bug.
                server = null;
                Thread.yield();
            }
            return server;
        } catch (Exception e) {
            System.err.println("自定义负载均衡算法错误");
        }
        return null;
    }
}
